import { isFunction } from 'lodash'

const sleep = delay => new Promise(resolve => setTimeout(resolve, delay))

const DEFAULT_CONFIG = {
  quantity: 3,
  wait: 3000
}

const getConfig = config => Object.assign({}, DEFAULT_CONFIG, config)

export default (method, config) => {
  const conf = getConfig(config)

  return (...args) => {
    const run = function () {
      return method(...args)
        .then(data => {
          if (isFunction(conf.callback) && !conf.callback(data)) {
            throw data
          } else {
            if (isFunction(conf.resolve)) {
              return conf.resolve(data, conf)
            }
            return Promise.resolve(data)
          }
        })
        .catch(error => {
          conf.quantity--
          conf.retry = conf.quantity
          if (conf.quantity <= 0) {
            if (isFunction(conf.reject)) {
              return conf.reject(error, conf)
            }
            return Promise.reject(error)
          } else {
            return sleep(conf.wait).then(run)
          }
        })
    }

    return run()
  }
}
